package cn.icatw.leetcode.editor.cn;
//给你链表的头结点 head ，请将其按 升序 排列并返回 排序后的链表 。
//
//
//
//
//
//
// 示例 1：
//
//
//输入：head = [4,2,1,3]
//输出：[1,2,3,4]
//
//
// 示例 2：
//
//
//输入：head = [-1,5,3,4,0]
//输出：[-1,0,3,4,5]
//
//
// 示例 3：
//
//
//输入：head = []
//输出：[]
//
//
//
//
// 提示：
//
//
// 链表中节点的数目在范围 [0, 5 * 10⁴] 内
// -10⁵ <= Node.val <= 10⁵
//
//
//
//
// 进阶：你可以在 O(n log n) 时间复杂度和常数级空间复杂度下，对链表进行排序吗？
//
// Related Topics 链表 双指针 分治 排序 归并排序 👍 2349 👎 0


//Java：排序链表
public class T148_SortList {
    public static void main(String[] args) {
        Solution solution = new T148_SortList().new Solution();
        // TO TEST
    }
    //leetcode submit region begin(Prohibit modification and deletion)

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     * int val;
     * ListNode next;
     * ListNode() {}
     * ListNode(int val) { this.val = val; }
     * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
        public ListNode sortList(ListNode head) {
            if (head == null || head.next == null) {
                return head;
            }
            // 快慢指针找到中点
            ListNode mid = getMid(head);
            ListNode right = mid.next;
            mid.next = null;
            return merge(sortList(head), sortList(right));
        }

        private ListNode merge(ListNode listNode, ListNode listNode1) {
            //构建虚拟节点
            ListNode dummy = new ListNode(-1);
            ListNode cur = dummy;
            while (listNode != null && listNode1 != null) {
                if (listNode.val < listNode1.val) {
                    cur.next = listNode;
                    listNode = listNode.next;
                } else {
                    cur.next = listNode1;
                    listNode1 = listNode1.next;
                }
                cur = cur.next;
            }
            cur.next = listNode == null ? listNode1 : listNode;
            return dummy.next;
        }

        private ListNode getMid(ListNode head) {
            ListNode slow = head;
            ListNode fast = head;
            while (fast.next != null && fast.next.next != null) {
                slow = slow.next;
                fast = fast.next.next;
            }
            return slow;
        }
    }

    //leetcode submit region end(Prohibit modification and deletion)
    public class ListNode {
        int val;
        ListNode next;

        ListNode() {
        }

        ListNode(int val) {
            this.val = val;
        }

        ListNode(int val, ListNode next) {
            this.val = val;
            this.next = next;
        }
    }
}
